package com.zlzlib.log.service.impl;

import com.zlzlib.common.util.MyDateUtils;
import com.zlzlib.log.bean.dto.ReqLogDto;
import com.zlzlib.log.bean.enums.LogType;
import com.zlzlib.log.bean.po.LogPo;
import com.zlzlib.log.bean.vo.LogListVo;
import com.zlzlib.log.service.LogService;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * @DateTime: 2023/3/9 17:33
 * @Author zlz
 * @Version 1.0
 */
@Service
@RequiredArgsConstructor
public class LogServiceImpl implements LogService {
    private final MongoTemplate mongoTemplate;

    @Override
    public LogListVo getLogPage(ReqLogDto dto) {
        Criteria criteria = new Criteria();
        //精确匹配
        if (StringUtils.hasLength(dto.getLogType())) {
            criteria.and("logType").is(dto.getLogType());
        }
        if (StringUtils.hasLength(dto.getThread())) {
            criteria.and("thread").is(dto.getThread());
        }
        //模糊匹配
        if (StringUtils.hasLength(dto.getClassName())) {
            criteria.and("className").regex(dto.getClassName());
        }
        if (StringUtils.hasLength(dto.getMethod())) {
            criteria.and("method").regex(dto.getMethod());
        }
        if (StringUtils.hasLength(dto.getParam())) {
            criteria.and("param").regex(dto.getParam());
        }
        if (StringUtils.hasLength(dto.getResult())) {
            criteria.and("result").regex(dto.getResult());
        }
        if (StringUtils.hasLength(dto.getHeader())) {
            criteria.and("header").regex(dto.getHeader());
        }
        if (StringUtils.hasLength(dto.getIp())) {
            criteria.and("ip").regex(dto.getIp());
        }
        //时间匹配
        if (dto.getDomain() > 0) {
            //时间之前
            Calendar calendar = Calendar.getInstance();
            calendar.add(Calendar.MINUTE, -dto.getDomain());
            criteria.and("createTime").gte(calendar.getTime());
        } else {
            //不能同时添加一个字段
            Date start = null;
            if (StringUtils.hasLength(dto.getStartTime())) {
                start = MyDateUtils.getDateFromStringYs(dto.getStartTime());
            }
            Date end = null;
            if (StringUtils.hasLength(dto.getEndTime())) {
                end = MyDateUtils.getDateFromStringYs(dto.getEndTime());
            }
            Criteria dateCriteria = null;
            if (start != null || end != null) {
                dateCriteria = criteria.and("createTime");
            }
            if (start != null) {
                //大于等于
                dateCriteria.gte(start);
            }
            if (end != null) {
                //小于等于
                dateCriteria.lte(end);
            }
        }
        // 用于计数的查询
        Query countQuery = new Query(criteria);
        // 获取总记录数
        long total = mongoTemplate.count(countQuery, LogPo.class, dto.getFileName());
        //分页
        Query query = new Query(criteria);
        // 设置排序规则
        Sort sort = Sort.by(dto.isTimeAsc() ? Sort.Direction.ASC : Sort.Direction.DESC,
                "createTime");
        // 创建分页对象
        int page = dto.getCurrent() - 1;
        if (page < 0) {
            page = 0;
        }
        Pageable pageable = PageRequest.of(page, dto.getSize(), sort);
        // 应用分页
        query.with(pageable);
        // 获取分页后的数据列表
        List<LogPo> content = mongoTemplate.find(query, LogPo.class, dto.getFileName());
        LogListVo logListVo = new LogListVo();
        logListVo.setTotals(total);
        List<LogListVo.LogVo> logVos = new ArrayList<>();
        for (LogPo logPo : content) {
            LogListVo.LogVo logVo = LogListVo.LogVo.poToVo(logPo);
            try {
                String type = LogType.valueOf(logVo.getLogType()).getDesc();
                logVo.setLogType(type);
            } catch (Exception ignored) {
                logVo.setLogType(logVo.getLogType());
            }
            logVos.add(logVo);
        }
        logListVo.setData(logVos);
        return logListVo;
    }

}
